package painter;

import gui.MainWindow;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.SwingUtilities;

public class JCanvasMouseEventListener extends MouseAdapter implements MouseMotionListener {

	private int shape_number; // 1 : line, 2 bezier
	private int etape_bezier; // 1 : tracé de la ligne, 2 : premier point de controle, 3 : deuxième point de controle
	private Color shape_color;
	private int shape_stroke;
	
	private JCanvas canvas;
	
	private Point startPoint;
	
	private Point endPoint;
	private Point ctrl1;
	
	private IDrawable currentDrawable;
	
	private MainWindow window;

	
	public JCanvasMouseEventListener(JCanvas canvas) {
		super();
		this.canvas = canvas;
		canvas.addMouseListener(this);
		canvas.addMouseMotionListener(this);
		startPoint = null;
		endPoint = null;
		ctrl1 = null;
		currentDrawable = null;
		
		shape_number = 1;
		etape_bezier = 1;
		
		shape_color = Color.BLACK;
		shape_stroke = 1;
	}
	
	public JCanvasMouseEventListener(JCanvas canvas, MainWindow window) {
		this(canvas);
		this.window = window;
	}
	
	@Override
	public void mousePressed(MouseEvent e) {
		if (window.currentPlayerIsDessinateur() && SwingUtilities.isLeftMouseButton(e)) {
			
			if (shape_number == 1) {
				
				startPoint = e.getPoint();
			}
			else if (shape_number == 2) {
				
				if (etape_bezier == 1) {
					startPoint = e.getPoint();
				}
			}
		}
	}
	
	@Override
	public void mouseDragged(MouseEvent e) {
		if (window.currentPlayerIsDessinateur() && SwingUtilities.isLeftMouseButton(e)) {
			
			if (shape_number == 1) {
				
				removeAndAddDrawable(createDrawable(startPoint, null, null, e.getPoint(), shape_number));
			}
			else if (shape_number == 2) {
				
				if (etape_bezier == 1) {
					
					removeAndAddDrawable(createDrawable(startPoint, startPoint, e.getPoint(), e.getPoint(), shape_number));
				}
				else if (etape_bezier == 2) {
					
					removeAndAddDrawable(createDrawable(startPoint, e.getPoint(), e.getPoint(), endPoint, shape_number));
				}
				else if (etape_bezier == 3) {

					removeAndAddDrawable(createDrawable(startPoint, ctrl1, e.getPoint(), endPoint, shape_number));
				}
			}
		}
	}
	
	@Override
	public void mouseReleased(MouseEvent e) {
		if (window.currentPlayerIsDessinateur() && SwingUtilities.isLeftMouseButton(e)) {
			
			if (shape_number == 1) {

				removeAndAddDrawable(createDrawable(startPoint, null, null, e.getPoint(), shape_number));
				window.connector.setLine(startPoint.x, startPoint.y, e.getPoint().x, e.getPoint().y);
				resetDrawing();
			}
			else if (shape_number == 2) {
				
				if (etape_bezier == 1) {
					if (currentDrawable != null)

					endPoint = e.getPoint();
					removeAndAddDrawable(createDrawable(startPoint, startPoint, endPoint, endPoint, shape_number));
					etape_bezier++;
				}
				else if (etape_bezier == 2) {

					ctrl1 = e.getPoint();
					removeAndAddDrawable(createDrawable(startPoint, ctrl1, ctrl1, endPoint, shape_number));
					etape_bezier++;
				}
				else if (etape_bezier == 3) {

					removeAndAddDrawable(createDrawable(startPoint, ctrl1, e.getPoint(), endPoint, shape_number));
					window.connector.setCourbe(startPoint.x, startPoint.y, ctrl1.x, ctrl1.y, e.getPoint().x, e.getPoint().y, endPoint.x, endPoint.y);
					resetDrawing();
				}
			}
		}
	}
	
	public IDrawable createDrawable(Point start, Point ctrl1, Point ctrl2, Point end, int shape_number) {
		
		IDrawable shape = null;
		
		if (shape_number == 1) {
			shape = new LineDrawable(shape_stroke, shape_color, start, end);
		}
		else if (shape_number == 2) {
			shape = new BezierDrawable(shape_stroke, shape_color, start, ctrl1, ctrl2, end);
		}
		
		return shape;
	}
	
	public void resetDrawing() {
		startPoint = null;
		endPoint = null;
		ctrl1 = null;
		currentDrawable = null;
		etape_bezier = 1;
	}
	
	public void setShapeNumber(int number) {
		shape_number = number;
	}
	
	public void setShapeColor(Color color) {
		shape_color = color;
	}
	
	public void setShapeStroke(int stroke) {
		shape_stroke = stroke;
	}
	
	private void removeAndAddDrawable(IDrawable drawable) {
		if (currentDrawable != null)
			canvas.removeDrawable(currentDrawable);
		
		currentDrawable = drawable;
		
		canvas.addDrawable(currentDrawable);
	}
}
